﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Windows.Forms;
using PayexpDAL;
using Utilities;
using System.Globalization;
using ExcelHandler;
using PayexpUserControls;

namespace Moneymatters
{
    // contains common code
    public partial class MainForm
    {
        #region Private Fields
        private decimal currentPettyCashBalance;
        private DataAccessHandler dataAccessHandlerCommonInstance = new DataAccessHandler();
        private string _previousTabName = "tabPageMain";
        private string _currentTabName = "tabPageMain";
        #endregion Private Fields

        #region Internal Fields

        internal delegate void DisplaySpecificTransactionsDelegate(List<int> idList);
        internal static AlfaRomeoEntities Context = new AlfaRomeoEntities();

        #endregion Internal Fields

        #region Properties

        private int NumberOfRecordsPerPage
        {
            get
            {
                try
                {
                   return int.Parse(SettingsAndStaticListLoader.ApplicationSettingList.Where(t => t.SettingName.Equals(Constants.AppSettingsKeys.RowsPerPage)).FirstOrDefault().SettingValue);
                }
                catch
                {
                    return 20; // default;
                }
            }
        }

        #endregion Properties

        #region Private Methods

        private void LoadStaticLists()
        {
            this.comboBoxBankNames.Items.Clear();
            foreach (StaticList staticListBank in SettingsAndStaticListLoader.BankNameList)
            {
                ComboBoxItem comboBoxItem = new ComboBoxItem(staticListBank.ListItemValue, staticListBank);
                this.comboBoxBankNames.Items.Add(comboBoxItem);
            }

            this.comboBoxBankNames.SelectedIndex = 0;
        }

        private string GetBankName(int? bankAccountsId)
        {
            if (bankAccountsId == null)
            {
                return string.Empty;
            }

            BankAccount bankAccount = SettingsAndStaticListLoader.BankAccountList.Where(t => t.Id.Equals(bankAccountsId.Value)).FirstOrDefault();
            if (bankAccount != null)
            {
                return bankAccount.BankDisplayName;
            }
            else
            {
                return string.Empty;
            }
        }

        private void tabControl_Selected(object sender, TabControlEventArgs e)
        {
            this._previousTabName = this._currentTabName;
            this._currentTabName = e.TabPage.Name;

            this.AcceptButton = null;
            if (e.TabPage.Name.Equals("tabPageReconcileTransactions"))
            {
                // Accept Button
                this.AcceptButton = this.buttonDisplayReconcile;
                
                if (this._previousTabName.Equals("tabPageMain") && 
                    this.mainPanelMap.Any(t => !t.Value.IsNew && t.Value.IsDirty))
                {
                    MessageBox.Show("You had made some changes in the 'Add Or Edit' tab but did not save the changes. Your changes done there would be lost if you reconile transactions from this view.", "Save your changes", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
               
            }
            else if (e.TabPage.Name.Equals("tabPageMain"))
            {
                // Accept Button
                this.AcceptButton = this.buttonSaveTransactionEntries;

                if (this._previousTabName.Equals("tabPageReconcileTransactions") && this._currentlyEditedTransactionMasterListMap.Count > 0)
                {
                    MessageBox.Show("You had made some changes in the 'Reconcile' tab but did not save the changes. Your changes done there would be lost if you add or edit transactions from this view.", "Save your changes", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }

                if (this.panelForScrollMain.Controls.Count == 0)
                {
                    //this.buttonAddRowMain.PerformClick();
                    this.buttonAddRowMain_Click(null, null);
                }
            }
            else if (e.TabPage.Name.Equals("tabPageBankAccountDetails"))
            {
                // Accept Button
                this.AcceptButton = this.buttonExportBankStatement;
                DisplayBankAccountDetails();
            }
            else if (e.TabPage.Name.Equals("tabPageViewPettyCashDetails"))
            {
                try
                {
                    this.Cursor = Cursors.WaitCursor;
                    DisplayPettyCashGridView();
                }
                finally
                {
                    this.Cursor = Cursors.Arrow;
                }
            }
            else if (e.TabPage.Name.Equals("tabPageSearchExportPrint"))
            {
                // Accept Button
                this.AcceptButton = this.buttonDisplayBankStatementsView;
            }

            else if (e.TabPage.Name.Equals("tabPageAddMasterData"))
            {
                PopulateParentSelectionForAddingChildren();
                PopulateApplicationSettings();
                PopulateIncomeHeadSelectionForDefaultValuesTreeView();
                PopulateExpenseHeadSelectionForDefaultValuesTreeView();
                PopulateComboBoxesForDefaultValueSelection();
                PopulateExistingDefaultValuesTreeView();
                this.radioButtonSetExpenseHeadApprovers.Checked = true;
            }

        }

        private void UpdatePettyCashLimit()
        {
            currentPettyCashBalance = this.dataAccessHandlerCommonInstance.GetAvailablePettyCash(MainForm.Context);
            this.toolStripStatusLabel1.Text = string.Format("Available Petty Cash is Rs {0}", currentPettyCashBalance);
        }

        private List<TransactionType> GetTransactionType(string commaSeparatedIdList)
        {
            string[] idList = commaSeparatedIdList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

            List<int> transTypeIdList = new List<int>();
            foreach (string id in idList)
            {
                // CHECK THIS CHANGE
                string idWithoutBrackets = id.Replace("[", string.Empty).Replace("]", string.Empty).Trim();
                //transTypeIdList.Add(int.Parse(id));
                transTypeIdList.Add(int.Parse(idWithoutBrackets));
            }

            return this.dataAccessHandlerCommonInstance.GetTransactionTypeListByIdList(transTypeIdList, MainForm.Context);
        }

        private List<TransactionType> ArrangeItems(List<TransactionType> inputList)
        {
            List<TransactionType> temp = new List<TransactionType>();

            while (inputList.Count > 0)
            {
                temp.Add(GetRoot(inputList));
            }
            return temp;
        }

        private TransactionType GetRoot(List<TransactionType> inputList)
        {
            TransactionType root = inputList.Where(t => !inputList.Any(r => r.Id.Equals(t.ParentId))).Select(m => m).FirstOrDefault();
            inputList.Remove(root);
            return root;
        }

        private decimal GetTotalExpensesInCashToBeSaved(List<TransactionMaster> transactionMasterListForSaveAndUpdate)
        {
            var transactionsWithCashExpenses = transactionMasterListForSaveAndUpdate.Where(t => t.Head.Equals("head_expense") &&
                                                                  t.TransactionModeValue.Equals("transaction_mode_cash") &&
                                                                  t.IsActive &&
                                                                  t.Id == 0);
            if (transactionsWithCashExpenses.Count() > 0)
            {
                return transactionsWithCashExpenses.Sum(r => r.TransactionAmount);
            }
            else
            {
                return 0;
            }
        }

        //private void LoadExpenseApprovers()
        //{
        //    try
        //    {
        //        SettingsAndStaticListLoader.ExpenseApproverList.AddRange(new DataAccessHandler().GetExpenseApproverList(MainForm.Context));
        //    }
        //    catch { }
        //}

        private void LoadBankAccounts()
        {
            try
            {
                //this.bankAccounts.Clear();
                //this.bankAccountsStaticList.Clear();

                //this.bankAccounts.AddRange(new DataAccessHandler().GetAllBankAccounts(Utils.FinancialYear, MainForm.Context));

                //foreach (BankAccount bankAccount in this.bankAccounts)
                //{
                //    StaticList bankAccountStaticListEntry = bankNameList.Where(t => t.ListItemCode.Equals(bankAccount.BankName)).FirstOrDefault();
                //    if (bankAccountStaticListEntry != null)
                //    {
                //        bankAccountsStaticList.Add(bankAccountStaticListEntry);
                //    }
                //}

                //set the bank account filter dropdown

                this.comboBoxBulkBankAccountSettingSelector.Items.Clear();
                foreach (BankAccount bankAccount in SettingsAndStaticListLoader.BankAccountList)
                {
                    ComboBoxItem comboBoxItem = new ComboBoxItem(bankAccount.BankDisplayName, bankAccount);
                    this.comboBoxBulkBankAccountSettingSelector.Items.Add(comboBoxItem);
                }

                if (this.comboBoxBulkBankAccountSettingSelector.Items.Count > 0)
                {
                    this.comboBoxBulkBankAccountSettingSelector.SelectedIndex = 0;
                }

            }
            catch { }
        }

        private void CreateRequiredFolderLocations()
        {
            try
            {
                //string voucherReceiptLocation = AppSettingsLoader.AppSettingsValuesMap[Constants.AppSettingsKeys.VoucherReceiptLocation];
                string voucherReceiptLocation = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.VoucherReceiptLocation);
                if (!Directory.Exists(voucherReceiptLocation))
                {
                    Directory.CreateDirectory(voucherReceiptLocation);
                }

                //string exportedFilesLocation = AppSettingsLoader.AppSettingsValuesMap[Constants.AppSettingsKeys.ExportedFilesLocation];
                string exportedFilesLocation = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.ExportedFilesLocation);
                if (!Directory.Exists(exportedFilesLocation))
                {
                    Directory.CreateDirectory(exportedFilesLocation);
                }
            }
            catch
            {

            }
        }

        //private string GetApproverNames(string squareBracketedCommaSeparatedList)
        //{
        //    List<int> approverIdList = squareBracketedCommaSeparatedList.GetIntegerListFromSquareBracketedCommaSeparatedString();
        //    if (approverIdList.Count == 0)
        //    {
        //        return string.Empty;
        //    }
        //    List<ExpenseApprover> requiredList = SettingsAndStaticListLoader.ExpenseApproverList.Where(t => approverIdList.Contains(t.Id)).ToList();
        //    return string.Join(", ", requiredList.Select(t => t.FirstName).ToArray());
        //}

        private void CreateTreeView(List<TransactionType> transactionTypeList, TreeView treeView)
        {
            TreeNode rootNode = new TreeNode(transactionTypeList.First().Name);
            treeView.Nodes.Add(rootNode);
            foreach (TransactionType transactionType in transactionTypeList.Where(t => t.ParentId == transactionTypeList.First().Id))
            {
                TreeNode topNode = new TreeNode(transactionType.Name);
                topNode.Tag = transactionType;
                rootNode.Nodes.Add(topNode);
                BuildTreeRecursively(topNode, transactionTypeList);
            }

            rootNode.Expand();
            foreach (TreeNode childNode in rootNode.Nodes)
            {
                childNode.Expand();
            }
        }

        private void BuildTreeRecursively(TreeNode parentNode, List<TransactionType> transactionTypeList)
        {
            TransactionType currentTransactionType = (TransactionType)parentNode.Tag;
            foreach (TransactionType transactionType in transactionTypeList.Where(t => t.ParentId == currentTransactionType.Id))
            {
                TreeNode childNode = new TreeNode(transactionType.Name);
                childNode.Tag = transactionType;
                parentNode.Nodes.Add(childNode);
                BuildTreeRecursively(childNode, transactionTypeList);
            }
        }

        private void DisplayRefreshViewMessage()
        {
            MessageBox.Show("You have either added or modified one or more transactions. Please refresh your view to avoid incorrect results.", "Please refresh", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void ExportFilteredResult(FilterCriteria filterCriteria, ProgressBar progressBarToUse, int numberOfRecordsPerPageToUse)
        {
            try
            {
                // query the database and get the data
                string exportFileName = "FilteredTransactionsReport_" + DateTime.Now.GetFileTime() + ".xlsx";
                //exportFileName = Path.Combine(AppSettingsLoader.AppSettingsValuesMap[Constants.AppSettingsKeys.ExportedFilesLocation], exportFileName);
                exportFileName = Path.Combine(SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.ExportedFilesLocation), exportFileName);

                
                FilteredTransactionsExportToExcel exportToExcel = new FilteredTransactionsExportToExcel(exportFileName, true, filterCriteria);
                int pageNumber = 0;
                int numberOfRecordsReturned = numberOfRecordsPerPageToUse;
                int totalNoOfRecords = 0;
                int currentProgress = 0;
                progressBarToUse.Visible = true;
                progressBarToUse.Value = currentProgress;



                while (numberOfRecordsReturned == numberOfRecordsPerPageToUse)
                {
                    List<TransactionMaster> filteredResult = this.dataAccessHandlerCommonInstance.GetFilteredTransactionMasterList(filterCriteria, pageNumber, numberOfRecordsPerPageToUse, out totalNoOfRecords, MainForm.Context);

                    if (filteredResult.Count == 0 && pageNumber == 0)
                    {
                        MessageBox.Show("No results matched your filter criteria.", "No results", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }

                    if (!filteredResult.Any(t => !t.IsActive) && filterCriteria.OnlyReconciledRecords && filterCriteria.BankAccountsIdList.Count == 1)
                    {
                        filteredResult = this.dataAccessHandlerCommonInstance.SetCurrentBalance(filteredResult, true, filterCriteria.BankAccountsIdList.First(), MainForm.Context);
                        filterCriteria.RunningBalanceComputed = true;
                    }

                    numberOfRecordsReturned = filteredResult.Count;
                    exportToExcel.ExportInBatches(filteredResult);

                    int percentIncrease = (numberOfRecordsReturned * 100) / totalNoOfRecords;
                    currentProgress = currentProgress + percentIncrease;
                    if (currentProgress <= 100)
                    {
                        progressBarToUse.Value = currentProgress;
                    }
                    else
                    {
                        progressBarToUse.Value = 100;
                    }



                    pageNumber++;
                }

                progressBarToUse.Value = 100;
                exportToExcel.CloseBatch();
                Process.Start(exportFileName);
            }
            catch
            {
                MessageBox.Show("Sorry, there was a problem trying to export the filtered transactions to an excel file. Please try again. If the problem persists, please contact your administrator", "Error when exporting", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Cursor = Cursors.Arrow;
                return;
            }
            finally
            {
                progressBarToUse.Visible = false;
                this.Cursor = Cursors.Arrow;
            }
        }

        private void ViewHistory(DataGridView dataGridViewToPickSelectedRowFrom)
        {
            if (dataGridViewToPickSelectedRowFrom == null || dataGridViewToPickSelectedRowFrom.SelectedRows.Count == 0)
            {
                MessageBox.Show("Please select a transaction from one of the views to view its history.", "Select a transaction", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            DataGridViewRow selectedRow = dataGridViewToPickSelectedRowFrom.SelectedRows[0]; // multi select not considered
            TransactionMaster transactionMaster = (TransactionMaster)selectedRow.Tag;
            if (transactionMaster != null)
            {
                DisplayHistory(transactionMaster.Id);
            }
        }

        private void EditSelected(DataGridView dataGridViewToPickSelectedRowFrom)
        {
            if (dataGridViewToPickSelectedRowFrom.SelectedRows.Count == 0)
            {
                MessageBox.Show("Please select a transaction to edit", "Select a transaction", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            DataGridViewRow selectedRow = dataGridViewToPickSelectedRowFrom.SelectedRows[0]; // multi select not considered
            TransactionMaster transactionMaster = (TransactionMaster)selectedRow.Tag;

            if (!transactionMaster.IsActive)
            {
                MessageBox.Show("You cannot edit a deleted transaction. It is being displayed only because you chose to. However, you could view its history.", "Cannot edit", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            // try removing all those rows from the main tab which were just added but no data was entered
            try
            {
                for (int index = 0; index < this.panelForScrollMain.Controls.Count; index++)
                {
                    Panel panel = (Panel)this.panelForScrollMain.Controls[index];
                    Button removeDeleteButton = (Button)panel.Controls[panel.Controls.Count - 1];
                    Guid parentPanelGuid = (Guid)panel.Tag;
                    if (mainPanelMap.ContainsKey(parentPanelGuid))
                    {
                        PanelDetails panelDetailsRemoveRow = (PanelDetails)mainPanelMap[parentPanelGuid];
                        if (!panelDetailsRemoveRow.IsDirty && removeDeleteButton.Text.Equals("Remove Row"))
                        {
                            mainRowDeleteButton_Click(removeDeleteButton, null);
                            index--;
                        }
                    }
                }
            }
            catch { }

           
            AddExistingOrClonedTransactionsMasterToMainDataEntryPanel(transactionMaster, false);

            //// remove the selected transaction from the grid view
            //this.dataGridViewTransactions.Rows.Remove(selectedRow);
            //this.dataGridViewChequeDetails.Rows.Clear();

            //if (this.dataGridViewTransactions.Rows.Count == 0)
            //{
            //    this.labelNumberOfRecords.Text = string.Empty;
            //}
            //else
            //{
            //    this.labelNumberOfRecords.Text = "(" + this.dataGridViewTransactions.Rows.Count.ToString() + ")";
            //}

            this.tabControl.SelectedIndex = 0;
        }

        private void vNavPaneDefaultValueSelectionTreeViews_ExpandedChanged(object sender, VIBlend.WinForms.Controls.vNavItemEventArgs e)
        {
            switch (e.Item.Name)
            {
                case "vNavPaneItemIncomeHeadsTreeView":
                    this.AcceptButton = this.buttonSaveIncomeHeadDefaultValues;
                    break;
                case "vNavPaneItemExpenseHeadsTreeView":
                    this.AcceptButton = this.buttonSaveExpenseHeadDefaultValues;
                    break;
                default:
                    break;
            }
            
        }

        private void vNavPaneAddMasterData_ExpandedChanged(object sender, VIBlend.WinForms.Controls.vNavItemEventArgs e)
        {
            switch (e.Item.Name)
            {
                case "vNavPaneItemAddEditAppSettings":
                    this.AcceptButton = this.buttonSaveAppSettings;
                    break;
                case "vNavPaneItemAddTransactionHeads":
                    this.AcceptButton = this.buttonAddSubHeads;
                    break;
                default:
                    break;
            }
        }

        #endregion Private Methods

        #region Public Methods
        #endregion Public Methods
    }
}